package com.jl;

import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.mysql.cj.jdbc.MysqlXADataSource;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.core.env.Environment;

import javax.sql.DataSource;

/**
 * 多数据源工具类
 */
public class JLDataSource {

    public static final String DATA_SOURCE_PREFIX = "spring.datasource.";

    /**
     * 创建DataSource
     *
     * @param environment
     * @param dataBase
     * @return
     */
    public static DataSource createDataSource(Environment environment, String dataBase) {
        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
        // 数据源唯一标识
        atomikosDataSourceBean.setUniqueResourceName(dataBase);
        //Druid连接池配置。spring-boot-2默认连接池hikari不支持MysqlXADataSource
        atomikosDataSourceBean.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
        // 最小连接数，默认1
        atomikosDataSourceBean.setMinPoolSize(environment.getProperty(DATA_SOURCE_PREFIX + "min", Integer.class));
        // 最大连接数，默认1
        atomikosDataSourceBean.setMaxPoolSize(environment.getProperty(DATA_SOURCE_PREFIX + "max", Integer.class));
        // 设置连接在池中被自动销毁之前保留的最大秒数。 可选，默认为0（无限制）。
        atomikosDataSourceBean.setMaxLifetime(environment.getProperty(DATA_SOURCE_PREFIX + "life", Integer.class));

        MysqlXADataSource mysqlXADataSource = new MysqlXADataSource();
        mysqlXADataSource.setDatabaseName(dataBase);
        mysqlXADataSource.setURL(environment.getProperty(DATA_SOURCE_PREFIX + dataBase + ".url"));
        mysqlXADataSource.setUser(environment.getProperty(DATA_SOURCE_PREFIX + dataBase + ".username"));
        mysqlXADataSource.setPassword(environment.getProperty(DATA_SOURCE_PREFIX + dataBase + ".password"));
        atomikosDataSourceBean.setXaDataSource(mysqlXADataSource);
        return atomikosDataSourceBean;
    }

    /**
     * 创建SqlSessionFactory
     *
     * @param dataSource
     * @return
     */
    public static SqlSessionFactory createSqlSessionFactory(DataSource dataSource) {
        try {
            SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
            MybatisConfiguration configuration = new MybatisConfiguration();
            //配置分页
            configuration.addInterceptor(new PaginationInterceptor());
            //配置打印sql语句
            configuration.setLogImpl(StdOutImpl.class);
            sessionFactoryBean.setConfiguration(configuration);
            sessionFactoryBean.setDataSource(dataSource);
            return sessionFactoryBean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static class Help {
        /**
         * class
         *
         * @return
         */
        public static void clas() {
            String msg = "@Configuration\n" +
                    "@MapperScan(basePackages = DemoDataSourceConfig.MAPPER, sqlSessionFactoryRef = DemoDataSourceConfig.SQL_SESSION_FACTORY)\n" +
                    "public class DemoDataSourceConfig {\n" +
                    "    //数据源名，对应yml\n" +
                    "    public final static String DATA_BASE = \"demo\";\n" +
                    "    public final static String DATA_SOURCE = DATA_BASE + \"DataSource\";\n" +
                    "    public final static String SQL_SESSION_FACTORY = DATA_BASE + \"SqlSessionFactory\";\n" +
                    "    //mapper路径,必须精确到各自的类包\n" +
                    "    public final static String MAPPER = \"com.mapper.\" + DATA_BASE;\n" +
                    "\n" +
                    "    /**\n" +
                    "     * 创建DataSource，一个数据库对应一个DataSource\n" +
                    "     */\n" +
                    "    @Bean(DATA_SOURCE)\n" +
                    "    public DataSource dataSource(Environment environment) {\n" +
                    "        return DataSourceUtil.createDataSource(environment, DATA_BASE);\n" +
                    "    }\n" +
                    "\n" +
                    "    /**\n" +
                    "     * 通过dataSource创建SqlSessionFactory\n" +
                    "     */\n" +
                    "    @Bean(SQL_SESSION_FACTORY)\n" +
                    "    public SqlSessionFactory sqlSessionFactory(@Qualifier(DATA_SOURCE) DataSource dataSource) {\n" +
                    "        return DataSourceUtil.createSqlSessionFactory(dataSource);\n" +
                    "    }\n" +
                    "}";
            System.out.println(msg);
        }

        /**
         * yml
         * @return
         */
        public static void yml() {
            String msg = "spring:\n" +
                    "  jta:\n" +
                    "    # 事务管理器唯一标识符，代码层只需要加上@Transactional就可生效事务\n" +
                    "    transaction-manager-id: txManager\n" +
                    "  datasource:\n" +
                    "    # 最小空闲连接\n" +
                    "    min: 5\n" +
                    "    # 最大连接数\n" +
                    "    max: 20\n" +
                    "    # 连接在池中被自动销毁之前保留的最大秒数\n" +
                    "    life: 60\n" +
                    "    # 数据源名\n" +
                    "    test:\n" +
                    "      url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false\n" +
                    "      username: root\n" +
                    "      password: root\n" +
                    "    # 数据源名\n" +
                    "    demo:\n" +
                    "      url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false\n" +
                    "      username: root\n" +
                    "      password: root";
            System.out.println(msg);
        }
    }
}
